﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CowsAndBulls
{
    class Computer
    {
        private bool[] isShowed = new bool[4];
        private int attempts = 1;
        private int[] generatedNumber = new int[4];
        private int cheats = 0;

        public Computer()
        {
            for (int i = 0; i < isShowed.Length; i++)
            {
                isShowed[i] = false;
            }
        }

        public bool[] IsShowed
        {
            get
            {
                return isShowed;
            }
            set
            {
                isShowed = value;
            }
        }

        public int Attempts
        {
            get
            {
                return attempts;
            }
            set
            {
                attempts = value;
            }
        }

        public int[] GeneratedNumber
        {
            get
            {
                return generatedNumber;
            }
            set
            {
                generatedNumber = value;
            }
        }

        public int Cheats
        {
            get
            {
                return cheats;
            }
            set
            {
                cheats = value;
            }
        }

        public void GenerateNumber(int? seed = null)
        {
            Random randNumber;

            if (seed == null)
            {
                randNumber = new Random();
            }
            else
            {
                randNumber = new Random(seed.Value);
            }

            HashSet<int> usedDigits = new HashSet<int>();
            for (int i = 0; i < this.GeneratedNumber.Length; i++)
            {
                int randInt;
                do
                {
                    randInt = randNumber.Next(0, 10);
                }
                while (usedDigits.Contains(randInt));

                //usedDigits.Add(randInt);
                GeneratedNumber[i] = randInt;
            }

            foreach (var item in GeneratedNumber)
            {
                Console.Write(item);
            }
            Console.WriteLine();
        }

        public string ShowBull()
        {
            string result = string.Empty;
            if (this.cheats == 4)
            {
                result = "GAME OVER! You have tryed to cheat for the fifth time, which means that you are an idiot!";
            }
            else
            {
                Random randNumber = new Random();
                int indexToShow = randNumber.Next(0, 4);
                while (isShowed[indexToShow])
                {
                    indexToShow = randNumber.Next(0, 4);
                }
                this.isShowed[indexToShow] = true;
                switch (indexToShow)
                {
                    case 0: result = string.Format("{0}XXX", this.generatedNumber[indexToShow]);
                        break;
                    case 1: result = string.Format("X{0}XX", this.generatedNumber[indexToShow]);
                        break;
                    case 2: result = string.Format("XX{0}X", this.generatedNumber[indexToShow]);
                        break;
                    case 3: result = string.Format("XXX{0}", this.generatedNumber[indexToShow]);
                        break;
                }
            }
            this.cheats++;

            return result;
        }

        public void ResetCheats()
        {
            this.cheats = 0;
            for (int i = 0; i < isShowed.Length; i++)
            {
                IsShowed[i] = false;
            }
        }

        public void ResetAttempts()
        {
            this.Attempts = 1;
        }

        public bool CheckNumber(int[] number)
        {
            int bullCount = 0;
            int cowCount = 0;
            int[] newGeneratedNumber = new int[4];

            for (int i = 0; i < 4; i++)
            {
                newGeneratedNumber[i] = generatedNumber[i];
            }

            //a loop for determing count of bulls
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (newGeneratedNumber[j] == number[i])
                    {
                        if (j == i)
                        {
                            bullCount++;
                            newGeneratedNumber[j] = -1;
                            number[i] = -2;
                            break;
                        }
                    }
                }
            }

            //a loop for determing count of cows
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (newGeneratedNumber[j] == number[i])
                    {
                        if (j != i)
                        {
                            cowCount++;
                            newGeneratedNumber[j] = -1;
                            number[i] = -2;
                            break;
                        }
                    }
                }
            }

            if (bullCount == 4)
            {
                String result = String.Format("Congratulations! You guessed the secret number in {0} attempts!", this.Attempts);
                if (this.attempts == 1)
                {
                    result = String.Format("Congratulations! You guessed the secret number in {0} attempt!", this.Attempts);
                }
                String add;
                if (this.cheats == 1)
                {
                    add = " and 1 cheat!";
                    result = result.Substring(0, result.Length - 1) + add;
                }
                else
                {
                    if (this.cheats != 0)
                    {
                        add = String.Format(" and {0} cheats!", this.cheats);
                        result = result.Substring(0, result.Length - 1) + add;
                    }
                }
                Console.WriteLine(result);
                return true;
            }
            else
            {
                Console.WriteLine("Wrong number! Bulls: {0}, Cows: {1}", bullCount, cowCount);
                this.attempts++;
                return false;
            }
        }
    }
}
